﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CatClient.Util;

namespace CatClient.Fusing
{
    // Token: 0x0200005E RID: 94
    internal class FuseManager : IDisposable
    {
        // Token: 0x060002FB RID: 763 RVA: 0x0000A6FF File Offset: 0x000088FF
        public FuseManager()
        {
            this._statisticses = new Dictionary<FuseType, FuseStatistics>();
        }

        // Token: 0x060002FC RID: 764 RVA: 0x0000A720 File Offset: 0x00008920
        public FuseManager AddStatistics(FuseStatistics statistics)
        {
            if (statistics == null)
            {
                LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error("statistics can not be null!");
                return this;
            }
            if (this._started)
            {
                LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error("can not add statistics when task started!");
                return this;
            }
            this._statisticses.Add(statistics.Type, statistics);
            statistics.OnFused += this.Statistics_OnFused;
            statistics.OnRecoveried += this.Statistics_OnRecoveried;
            return this;
        }

        // Token: 0x060002FD RID: 765 RVA: 0x0000A7A4 File Offset: 0x000089A4
        public void Increment(FuseType type)
        {
            if (!this._started)
            {
                return;
            }
            FuseStatistics fuseStatistics;
            if (this._statisticses.TryGetValue(type, out fuseStatistics))
            {
                fuseStatistics.Increment();
                return;
            }
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Warn("unknow fuse statistics type for increment: " + type);
        }

        // Token: 0x060002FE RID: 766 RVA: 0x0000A7F4 File Offset: 0x000089F4
        public void Increment(FuseType type, object value)
        {
            if (!this._started)
            {
                return;
            }
            FuseStatistics fuseStatistics;
            if (this._statisticses.TryGetValue(type, out fuseStatistics))
            {
                fuseStatistics.Increment(value);
                return;
            }
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Warn("unknow fuse statistics type for increment: " + type);
        }

        // Token: 0x060002FF RID: 767 RVA: 0x0000A848 File Offset: 0x00008A48
        public void Start()
        {
            if (this._started)
            {
                return;
            }
            object locker = this._locker;
            lock (locker)
            {
                if (this._started)
                {
                    return;
                }
                foreach (FuseStatistics fuseStatistics in this._statisticses.Values)
                {
                    try
                    {
                        fuseStatistics.Start();
                    }
                    catch (Exception exception)
                    {
                        LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error("error occur when start(init) statistics", exception);
                    }
                }
            }
            this._started = true;
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Info(string.Format("{0} statisticses has been started.[{1}]", this._statisticses.Count, string.Join<FuseType>(",", this._statisticses.Keys)));
        }

        // Token: 0x06000300 RID: 768 RVA: 0x0000A954 File Offset: 0x00008B54
        private void Statistics_OnFused(object sender, EventArgs e)
        {
            FuseStatistics fuseStatistics = (FuseStatistics)sender;
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Warn(string.Format("{0} statistics has been fused!", fuseStatistics.Type));
            if (!fuseStatistics.Running)
            {
                return;
            }
            object locker = this._locker;
            lock (locker)
            {
                if (fuseStatistics.Running)
                {
                    CatConfig.Config.Domain.Enabled = false;
                    List<Task> list = new List<Task>();
                    foreach (FuseStatistics fuseStatistics2 in this._statisticses.Values)
                    {
                        try
                        {
                            if (fuseStatistics != fuseStatistics2)
                            {
                                list.Add(fuseStatistics2.Stop());
                            }
                        }
                        catch (Exception exception)
                        {
                            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error("error occur when stop statistics", exception);
                        }
                    }
                    if (!Task.WaitAll(list.ToArray(), 61000))
                    {
                        IEnumerable<Task> source = from item in list
                                                   where item.Status != TaskStatus.RanToCompletion
                                                   select item;
                        string arg = string.Join(", ", from item in source
                                                       select item.GetType().Name + " -> " + item.Status);
                        LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error(string.Format("failed to stop fuse statistics.[{0}]", arg));
                    }
                    Cat.ClearSenderQueue();
                }
            }
        }

        // Token: 0x06000301 RID: 769 RVA: 0x0000AB18 File Offset: 0x00008D18
        private void Statistics_OnRecoveried(object sender, EventArgs e)
        {
            FuseStatistics fuseStatistics = (FuseStatistics)sender;
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Warn(string.Format("{0} statistics has been recoveried!", fuseStatistics.Type));
            object locker = this._locker;
            lock (locker)
            {
                foreach (FuseStatistics fuseStatistics2 in this._statisticses.Values)
                {
                    try
                    {
                        if (fuseStatistics != fuseStatistics2)
                        {
                            fuseStatistics2.Start();
                        }
                    }
                    catch (Exception exception)
                    {
                        LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error("error occur when start(recovery) statistics", exception);
                    }
                }
                CatConfig.Config.Domain.Enabled = true;
            }
        }

        // Token: 0x06000302 RID: 770 RVA: 0x0000AC08 File Offset: 0x00008E08
        public void Dispose()
        {
            foreach (FuseStatistics fuseStatistics in this._statisticses.Values)
            {
                try
                {
                    fuseStatistics.Dispose();
                }
                catch (Exception exception)
                {
                    LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Error("error occur when dispose statistics", exception);
                }
            }
        }

        // Token: 0x04000154 RID: 340
        private readonly object _locker = new object();

        // Token: 0x04000155 RID: 341
        private volatile bool _started;

        // Token: 0x04000156 RID: 342
        private readonly Dictionary<FuseType, FuseStatistics> _statisticses;
    }
}
